package me.hacket.netrequestpro.base;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;

import com.google.gson.reflect.TypeToken;

import me.hacket.library.HJsonBody;
import me.hacket.library.HNet;
import me.hacket.library.HNetConfig;
import me.hacket.library.Header;
import me.hacket.library.NetworkCreator;
import me.hacket.library.callback.RequestError;
import me.hacket.library.callback.TemplateCallback;
import me.hacket.library.request.BaseResponse;
import me.hacket.library.util.LogUtils;
import me.hacket.library.util.RunningContext;
import me.hacket.netrequestpro.bean.LogMessageRequest;
import me.hacket.netrequestpro.bean.LogMessageResponse;

/**
 * 网络请求管理
 * Created by hacket on 2016/8/15.
 */
public class NetManager {

    private static final String TAG = NetManager.class.getSimpleName();

    //    private static final String BASEURL = "https://service.shierfan.com/";
    private static final String BASEURL = "http://218.17.0.92:51515/";
    private static final String BASE_PATH = "cloud_sales/api/v1/";
    //    private static final String BASE_PATH = "";

    //    private static final String BASEURL = "http://172.17.1.123:8080"; // 麻痹url没带http://
    //    private static final String BASE_PATH = "";// null; // "cloud_sales/api/v1/";

    private static final String LOG_UPLOAD_BASE_URL =
            true ? "http://218.17.0.92:51515/" : "http://netlog.shierfan.com:59000/";
    private static final String LOG_UPLOAD_PATH = "android/log_report_gateway";

    private NetworkCreator mRequest;

    private static volatile NetManager mInstance;
    private HNet mConnect;

    private NetManager() {
        init();
    }

    private void init() {
        mConnect = HNet.connect();

        // 全局header
        Header header = new Header.Builder()
                .add("Charset", "UTF-8")
                .add("Content-Type", "application/x-javascript")
                .add("Content-Type", "application/json;charset=utf-8")
                .add("Accept-Encoding", "gzip,deflate")
                .build();

        // 全局配置
        HNetConfig netConfig = new HNetConfig.Builder()
                .setContext(RunningContext.getAppContext())
                .setBaseUrl(BASEURL)
                .addHeader(header)
                .build();

        // 初始化
        HNet.init(netConfig);

        // 创建请求
        mRequest = mConnect.createRequest(netConfig);
    }

    public static NetManager getInstance() {
        if (mInstance == null) {
            synchronized(NetManager.class) {
                if (mInstance == null) {
                    mInstance = new NetManager();
                }
            }
        }
        return mInstance;
    }

    /**
     * POST, 其中response字段为{}JsonObject
     *
     * @param pathUrl       pathUrl, 不要以/ 开头
     * @param requestBody   请求体Bean
     * @param responseClazz 响应体Class
     * @param requestTag    请求TAG
     * @param callback      回调
     * @param <T>           T
     * @param <V>           V
     */
    public <T, V> void post(@Nullable String pathUrl, @NonNull V requestBody, @NonNull Class<T> responseClazz,
                            @Nullable String requestTag, @Nullable TemplateCallback<T> callback) {

        HJsonBody hJsonBody = new HJsonBody.Builder()
                .setBody(requestBody)
                .build();

        mRequest.post(hJsonBody)
                .baseUrl(buildUrl(pathUrl))
                .fromTemplate()
                .toBean(responseClazz)
                .execute(requestTag, callback);
    }

    /**
     * POST, 其中response字段为[]JsonArray
     *
     * @param pathUrl           pathUrl, 不要以/ 开头
     * @param requestBody       请求体Bean
     * @param responseTypeToken 响应体TypeToken
     * @param requestTag        请求TAG
     * @param callback          回调
     * @param <T>               T
     * @param <V>               V
     */
    public <T, V> void post(@Nullable String pathUrl, @NonNull V requestBody, @NonNull TypeToken<T> responseTypeToken,
                            @Nullable String requestTag, @Nullable TemplateCallback<T> callback) {

        HJsonBody hJsonBody = new HJsonBody.Builder()
                .setBody(requestBody)
                .build();

        mRequest.post(hJsonBody)
                .baseUrl(buildUrl(pathUrl))
                .fromTemplate()
                .toBean(responseTypeToken)
                .execute(requestTag, callback);
    }

    /**
     * 日志上报
     *
     * @param level
     * @param content
     */
    public void postLogUpload(@LogMessageRequest.LogUploadLevel.LOG_UPLOAD_LEVEL int level,
                              @NonNull final String content) {

        LogMessageRequest request = new LogMessageRequest();
        request.log.add(new LogMessageRequest.LogUploadLevel(level, content));
        HJsonBody jsonBody = new HJsonBody.Builder()
                .setBody(request)
                .build();

        mRequest.post(jsonBody).baseUrl(LOG_UPLOAD_BASE_URL).pathUrl(LOG_UPLOAD_PATH).fromTemplate().toBean(
                LogMessageResponse.class).execute("", new TemplateCallback<LogMessageResponse>() {
            @Override
            public void onResponseStatus(@BaseResponse.RESULT_CODE int code, String desc) {
                LogUtils.i(TAG, "log upload code:" + code + ", desc:" + desc);
            }

            @Override
            public void onResponseError(RequestError error) {
                LogUtils.i(TAG, error.getErrorMsg());
            }

            @Override
            public void onResponseSuccess(LogMessageResponse logMessageResponse) {

            }
        });
    }

    /**
     * 构建url
     *
     * @param pathUrl 不要以/开头
     *
     * @return
     */
    private String buildUrl(String pathUrl) {
        if (TextUtils.isEmpty(pathUrl)) {
            pathUrl = "";
        }
        String url = new CommonParams.Builder()
                .baseUrl(BASEURL)
                .pathUrl(BASE_PATH + pathUrl)
                .isNeedCommonParams(true)
                .build()
                .buildUrl();
        LogUtils.i(TAG, "buildUrl : " + url);
        return url;
    }

}
